package edu.mbb.cloud.nacos;

import edu.mbb.cloud.nacos.listen.ConfigService;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.cloud.bootstrap.config.PropertySourceLocator;
import org.springframework.core.env.CompositePropertySource;
import org.springframework.core.env.Environment;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.util.StringUtils;

import java.io.StringReader;
import java.util.*;

/**
 * 加载配置的核心类
 */
public class MbbPropertySourceLocator implements PropertySourceLocator {


    public static Map<String,NacosProperSource> properSourceMap=new HashMap<>();
    private MbbConfigProPerties mbbConfigProPerties;

    public MbbPropertySourceLocator(MbbConfigProPerties mbbConfigProPerties){
        this.mbbConfigProPerties=mbbConfigProPerties;
    }


    @Override
    public PropertySource<?> locate(Environment environment) {


        String serverAddr = mbbConfigProPerties.getServerAddr();
        String namespace = mbbConfigProPerties.getNamespace();
        String fileExtension = mbbConfigProPerties.getFileExtension();
        String group = mbbConfigProPerties.getGroup();
        String dataIdPrefix = mbbConfigProPerties.getPrefix();
        String name = mbbConfigProPerties.getName();
        if (StringUtils.isEmpty(dataIdPrefix)) {
            dataIdPrefix = name;
        }

        if (StringUtils.isEmpty(dataIdPrefix)) {
            dataIdPrefix = environment.getProperty("spring.application.name");
        }
        Properties properties=new Properties();
        Map<String,String> map=new HashMap<>();

        map.put("serverAddr",mbbConfigProPerties.getServerAddr());
        map.put("namespace",namespace);
        properties.putAll(map);
        ConfigService configService = mbbConfigProPerties.configServiceInstance(properties);
        mbbConfigProPerties.setConfigService(configService);
        CompositePropertySource composite = new CompositePropertySource(
                "myNacos");
       loadNaoce(composite,serverAddr,namespace,fileExtension,group,dataIdPrefix,environment,configService);

        return composite;
    }

    private void loadNaoce(CompositePropertySource composite,String serverAddr, String namespace, String fileExtension, String group, String dataId,Environment environment,ConfigService configService) {
        try {
        //会获取两个
        //String url="http://"+serverAddr+"/nacos/v1/cs/configs?dataId="+dataId+"."+fileExtension+"&group="+group+"&tenant="+namespace+"&namespaceId="+namespace;
        //getServerConfig nacos都在这里面封装了 请求
        String s1 =  configService.getConfig(dataId+"."+fileExtension,group);
        Properties properties1 = getProperties(s1, fileExtension);
        NacosProperSource nacosProperSource1 = nacosProperSourceBulid(namespace, group, dataId+"."+fileExtension, properties1);
        properSourceMap.put(namespace+"+"+group+"+"+dataId+"."+fileExtension,nacosProperSource1);
        composite.addFirstPropertySource(nacosProperSource1);
        for(String activeProfiles : environment.getActiveProfiles()){
          // String url1="http://"+serverAddr+"/nacos/v1/cs/configs?dataId="+dataId+"-"+activeProfiles+"."+fileExtension+"&group="+group+"&tenant="+namespace+"&namespaceId="+namespace;

            String s = configService.getConfig(dataId+"-"+activeProfiles+"."+fileExtension,group);
            Properties properties2 = getProperties(s, fileExtension);
            NacosProperSource nacosProperSource = nacosProperSourceBulid(namespace, group, dataId+"-"+activeProfiles+"."+fileExtension, properties2);
            properSourceMap.put(namespace+"+"+group+"+"+dataId+"-"+activeProfiles+"."+fileExtension,nacosProperSource);
            composite.addFirstPropertySource(nacosProperSource);
        }

        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public NacosProperSource nacosProperSourceBulid(String namespace , String group, String dataId,Properties properties1){
        NacosProperSource nacosProperSource=new NacosProperSource(group,dataId,namespace,dataId,propertiesToMap(properties1));
        return nacosProperSource;
    }

    //抄的 nacos
    private Map<String, Object> propertiesToMap(Properties properties) {
        Map<String, Object> result = new HashMap<>(16);
        Enumeration<String> keys = (Enumeration<String>) properties.propertyNames();
        while (keys.hasMoreElements()) {
            String key = keys.nextElement();
            Object value = properties.getProperty(key);
            if (value != null) {
                result.put(key, ((String) value).trim());
            }
            else {
                result.put(key, null);
            }
        }
        return result;
    }
    //获取对应的 yml解析

    public Properties getProperties(String data,String fileExtension) throws Exception{
        if (fileExtension.equalsIgnoreCase("properties")) {
           return propertiesSourceParse(data);
        }else if(fileExtension.equalsIgnoreCase("yaml") || fileExtension.equalsIgnoreCase("yml")){
           return YMLSourceParse(data);
        }
        return null;
    }

    public Properties YMLSourceParse(String data){
        YamlPropertiesFactoryBean yamlFactory = new YamlPropertiesFactoryBean();
        yamlFactory.setResources(new ByteArrayResource(data.getBytes()));
        return yamlFactory.getObject();
    }

    public Properties propertiesSourceParse(String data) throws Exception{
        Properties properties = new Properties();
        properties.load(new StringReader(data));
        return properties;
    }

}
